﻿using MQTTnet;
using MQTTnet.Client.Receiving;
using MQTTnet.Server;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;

namespace Server
{
    public partial class MainWindow : Window
    {
        private IMqttServer _mqttServer;
        private IMqttServerOptions _mqttServerOptions;
        private Dictionary<string, List<string>> _clientSubscriptions;  // 用来存储每个客户端的订阅主题

        public MainWindow()
        {
            InitializeComponent();
            _clientSubscriptions = new Dictionary<string, List<string>>();
            txtServerIP.Text = "127.0.0.1";
            txtServerPort.Text = "1155";
            txtUsername.Text = "123";
            txtPassword.Text = "123";
        }

        // 启动服务器按钮点击事件
        private async void btnStartServer_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取用户输入的服务器配置信息
                string ip = txtServerIP.Text;
                int port = int.Parse(txtServerPort.Text);
                string username = txtUsername.Text;
                string password = txtPassword.Text;

                // 配置 MQTT 服务器选项
                var optionsBuilder = new MqttServerOptionsBuilder()
                    .WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Parse(ip))  // 设置服务器 IP 地址
                    .WithDefaultEndpointPort(port)                                      // 设置端口
                    .WithConnectionValidator(context =>
                    {
                        // 连接验证（使用输入的用户名和密码）
                        if (context.Username != username || context.Password != password)
                        {
                            context.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
                        }
                    });

                _mqttServerOptions = optionsBuilder.Build();

                // 创建 MQTT 服务器实例
                _mqttServer = new MqttFactory().CreateMqttServer();

                // 启动 MQTT 服务器
                await _mqttServer.StartAsync(_mqttServerOptions);
                AppendLog("服务器已启动...");

                // 启用停止服务器按钮
                btnStopServer.IsEnabled = true;
                btnStartServer.IsEnabled = false;

                // 订阅客户端连接、断开事件
                _mqttServer.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(e =>
                {
                    // 更新UI线程
                    Dispatcher.Invoke(() =>
                    {
                        AppendLog($"客户端连接: {e.ClientId}");
                        lstConnectedClients.Items.Add(e.ClientId);
                    });
                });

                _mqttServer.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(e =>
                {
                    // 更新UI线程
                    Dispatcher.Invoke(() =>
                    {
                        AppendLog($"客户端断开: {e.ClientId}");
                        lstConnectedClients.Items.Remove(e.ClientId);

                        // 清理订阅记录
                        _clientSubscriptions.Remove(e.ClientId);
                    });
                });

                // 处理接收到的消息
                _mqttServer.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(e =>
                {
                    // 更新UI线程
                    Dispatcher.Invoke(() =>
                    {
                        AppendLog($"接收到消息 - 主题: {e.ApplicationMessage.Topic}, 内容: {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");

                        // 获取订阅该主题的客户端
                        foreach (var clientId in _clientSubscriptions.Keys)
                        {
                            if (_clientSubscriptions[clientId].Contains(e.ApplicationMessage.Topic))
                            {
                                AppendLog($"消息已推送给:{clientId}");
                            }
                        }
                    });
                });

                // 订阅主题信息处理
                _mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(e =>
                {
                    string clientId = e.ClientId;
                    string topic = e.TopicFilter.Topic;

                    // 更新UI线程
                    Dispatcher.Invoke(() =>
                    {
                        if (!_clientSubscriptions.ContainsKey(clientId))
                        {
                            _clientSubscriptions[clientId] = new List<string>();
                        }

                        if (!_clientSubscriptions[clientId].Contains(topic))
                        {
                            _clientSubscriptions[clientId].Add(topic);
                            AppendLog($"客户端 {clientId} 订阅了主题: {topic}");

                            // 更新主题列表
                            lstSubscriptionGroups.Items.Add($"{clientId} 订阅了主题 {topic}");
                        }
                    });
                });
            }
            catch (Exception ex)
            {
                AppendLog($"启动服务器失败: {ex.Message}");
            }
        }

        // 停止服务器按钮点击事件
        private async void btnStopServer_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 停止 MQTT 服务器
                await _mqttServer.StopAsync();
                AppendLog("服务器已停止...");

                // 启用启动按钮，禁用停止按钮
                btnStartServer.IsEnabled = true;
                btnStopServer.IsEnabled = false;
            }
            catch (Exception ex)
            {
                AppendLog($"停止服务器失败: {ex.Message}");
            }
        }

        // 日志输出方法
        private void AppendLog(string message)
        {
            txtServerLog.AppendText($"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}");
            txtServerLog.ScrollToEnd();
        }

        // 窗口关闭时，确保停止服务器
        private async void Window_Closed(object sender, EventArgs e)
        {
            if (_mqttServer != null && _mqttServer.IsStarted)
            {
                await _mqttServer.StopAsync();
            }
        }
    }
}
